/**
 * Router_LSA.java
 *
 * @author Hagen Boehm
 */


package SSF.OS.OSPFv2;


import java.util.*;
import SSF.OS.*;


// ========================= class SSF.OS.OSPFv2.Router_LSA ============================ //
/**
 * This class implements an OSPF Router Link State Advertisement. The following from RFC 2328 was
 * not included:
 * 1.) TOS
 * 2.) TOS Metric 
 */

public class Router_LSA extends ProtocolMessage {
  
  /** Indicates the V-bit in an Router-LSA (Virtual)*/
  public boolean isVirtLinkEndPoint;
  /** Indicates the E-bit in an Router-LSA (External)*/
  public boolean isASBoundaryRouter;
  /** Indicates the B-bit in an Router-LSA (Border)*/
  public boolean isAreaBorderRouter;
  /** The number of router links described in this LSA. */ 
  private int numOfLinks;
  /** A Vector collecting  all link descriptions (LinkInfo) belonging to this Router_LSA. */ 
  public Vector links;

  // ----------------------------- constructor Router_LSA ---------------------------- //

  public Router_LSA(boolean v, boolean e, boolean b) {
    isVirtLinkEndPoint = v;
    isASBoundaryRouter = e;
    isAreaBorderRouter = b;
    numOfLinks = 0;
    this.links = new Vector();
  }

  // ----------------------------- Router_LSA.carryPayload ---------------------------- //

  public void carryPayload(ProtocolMessage payload) {
    System.err.println("** Warning: Router_LSA can't take payload; dropping.");
  }

  // ------------------------------ Router_LSA.addLink ------------------------------- //
  /** add a new link info to this router LSA. */
  public void addLink(LinkInfo link) {
    links.add(link);
    numOfLinks++;
  }

  // ----------------------------- Router_LSA.getNumOfLinks -------------------------- //
  /** Return the Number of link informations stored in this Router_LSA. */
  public int getNumOfLinks() {
    return numOfLinks;
  }

  // ------------------------------- Router_LSA.bytecount ---------------------------- //
  /** Return the total size (in bytes) of this Router_LSA body. 
   *  All and only fields specified in RFC 2328 are included in calculation!!!
   */
  public int bytecount(){
    return header_bytecount();
  }

  // ---------------------------- Router_LSA.header_bytecount ------------------------- //
  /** Return the size (in bytes) of this header only, don't include a payload. 
   *  Router_LSA Classes don't have payload.
   */
  public int header_bytecount(){
    return (4 + links.size() * LinkInfo.size());
  }

  // -------------------------------- Router_LSA.copy ---------------------------------- //
  /** Return an exact copy of this data structure. This method is used indirectly by the
   *  Neighbor Data Structure to send a copy of a Router LSA to its associated Neighbor.
   */
  public ProtocolMessage copy() {
    Router_LSA routerLSA = new Router_LSA(isVirtLinkEndPoint, isASBoundaryRouter, isAreaBorderRouter);
    routerLSA.numOfLinks = 0;
    for (Enumeration e = links.elements(); e.hasMoreElements(); ) {
      routerLSA.addLink(((LinkInfo)e.nextElement()).copy());
    }
    return routerLSA;
  }

  // ------------------------------ Router_LSA.equals ------------------------------- //
  /** Take a Router_LSA an compare it to this Router_LSA. If there is no difference
   *  between them return true else false.
   *  @param test Object referencing a Router_LSA to compare.
   *  @return boolean value indicating whether the contents of the Router_LSAs are equal.
   */
  public boolean equals(Object test) {
    if (test instanceof Router_LSA) {
      Router_LSA testRouterLSA = (Router_LSA)test;
      if (testRouterLSA.isVirtLinkEndPoint != isVirtLinkEndPoint) return false;
      if (testRouterLSA.isASBoundaryRouter != isASBoundaryRouter) return false;
      if (testRouterLSA.isAreaBorderRouter != isAreaBorderRouter) return false;
      if (testRouterLSA.numOfLinks != numOfLinks) return false;
      LinkInfo link;
      Enumeration testEnum = testRouterLSA.links.elements();
      Enumeration enum     = links.elements();
      for (int i = 1; i <= numOfLinks; i++) {
        link = (LinkInfo)enum.nextElement();
        if (!link.compare((LinkInfo)testEnum.nextElement())) return false;
      }
      return true;
    }
    return false;
  }

} //end class Router_LSA


